package com.jiajia.study.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 *
 * 一、 使用NIO 完成网络通信的三个核心：
 *
 *      1 通道 Channel 负责连接
 *
 *      2 缓冲区 Buffer 负责数据的存取
 *
 *      3 选择器 Selector  是SelectChannel 的多路复用器，用于监控SelectableChannel的IO状况
 *
 *
 *
 * @author : zjj
 * @date : 2021-04-21 14:01
 */
public class SocketClient {

    public static void main(String[] args) throws IOException {
//        testServer();

        testClient();
    }

    /**
     * 客户端测试
     */
    private static void testClient() throws IOException {
        // 1 获取SocketChannel
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8888));

        FileChannel fileChannel = FileChannel.open(Paths.get("test.mp4"), StandardOpenOption.READ);

        // 2 分配指定大小的缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // 3 读取本地文件
        while(fileChannel.read(buffer) != -1){
            buffer.flip();
            socketChannel.write(buffer);
            buffer.clear();
        }


        // 4 关闭通道
        fileChannel.close();
        socketChannel.close();
    }

    private static void testServer() throws IOException {
        // 1 获取通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        FileChannel fileChannel = FileChannel.open(Paths.get("beauty5.mp4"),StandardOpenOption.READ,StandardOpenOption.WRITE
        ,StandardOpenOption.CREATE);


        // 2 绑定连接

        serverSocketChannel.bind(new InetSocketAddress(8888));

        // 3 获取客户端的连接通道

        SocketChannel socketChannel = serverSocketChannel.accept();

        // 4 分配指定大小的缓冲区

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        // 5 接收客户端的数据，并保存到本地
        while(socketChannel.read(byteBuffer) != -1){
            byteBuffer.flip();
            fileChannel.write(byteBuffer);
            byteBuffer.clear();
        }

        // 6 关闭通道

        socketChannel.close();
        fileChannel.close();
        serverSocketChannel.close();


    }
}
